package com.atguigu.gmall.search.listener;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.search.feign.GmallPmsClient;
import com.atguigu.gmall.search.feign.GmallWmsClient;
import com.atguigu.gmall.search.pojo.Goods;
import com.atguigu.gmall.search.pojo.SearchAttrValueVo;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class GoodsListener {

    @Autowired
    private GmallPmsClient pmsClient;

    @Autowired
    private GmallWmsClient wmsClient;

    @Autowired
    private ElasticsearchRestTemplate restTemplate;
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("SEARCH.SYNCDATA.QUEUE"),
            exchange = @Exchange(value = "PMS.INSERT.EXCHANGE",ignoreDeclarationExceptions = "true",type = ExchangeTypes.TOPIC),
            key = "item.insert"
    ))
    public void syncData(Long spuId, Channel channel, Message message) throws IOException {
        //判断消息是否为空
        try {
            if (spuId==null) {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            }
            //消费消息 同步数据
            //根据spuId查询spu信息
            ResponseVo<SpuEntity> spuEntityResponseVo = pmsClient.querySpuById(spuId);
            SpuEntity spuEntity = spuEntityResponseVo.getData();
            ResponseVo<List<SkuEntity>> skuResponseVO = pmsClient.querySkusBySpuId(spuId);
            List<SkuEntity> skuEntities = skuResponseVO.getData();

            //桶一个spu品牌和分类是一样的，在外部获取
            ResponseVo<BrandEntity> brandEntityResponseVo = pmsClient.queryBrandById(spuEntity.getBrandId());
            BrandEntity brandEntity = brandEntityResponseVo.getData();

            ResponseVo<CategoryEntity> categoryEntityResponseVo = pmsClient.queryCategoryById(spuEntity.getCategoryId());
            CategoryEntity categoryEntity = categoryEntityResponseVo.getData();

            //将sku集合转化为goods集合 导入es
            List<Goods> goodsList = skuEntities.stream().map(skuEntity -> {
                Goods goods = new Goods();
                //设置商品列表所需字段
                goods.setSkuId(skuEntity.getId());
                goods.setTitle(skuEntity.getTitle());
                goods.setSubtitle(skuEntity.getSubtitle());
                goods.setDefaultImage(skuEntity.getDefaultImage());
                goods.setPrice(skuEntity.getPrice().doubleValue());

                //设置创建时间
                goods.setCreateTime(spuEntity.getCreateTime());

                //根据skuId查询库存信息 并设置
                ResponseVo<List<WareSkuEntity>> wareSkuVO = wmsClient.queryWareSkusBySkuId(skuEntity.getId());
                List<WareSkuEntity> wareSkuEntities = wareSkuVO.getData();
                if (!CollectionUtils.isEmpty(wareSkuEntities)) {
                    //任何一个库存有货，就认为有货
                    goods.setStore(wareSkuEntities.stream().anyMatch(wareSkuEntity -> wareSkuEntity.getStock() - wareSkuEntity.getStockLocked() > 0));
                    goods.setSales(wareSkuEntities.stream().map(WareSkuEntity::getSales).reduce((a, b) -> a + b).get());
                }

                //设置品牌相关字段
                goods.setBrandId(brandEntity.getId());
                goods.setBrandName(brandEntity.getName());
                goods.setLogo(brandEntity.getLogo());

                //设置分类相关字段
                goods.setCategoryId(categoryEntity.getId());
                goods.setCategoryName(categoryEntity.getName());

                //设置检索属性和值
                ResponseVo<List<SkuAttrValueEntity>> skuAttrValueVO = pmsClient.querySkuAttrValuesByCidAndskuId(skuEntity.getCategoryId(), skuEntity.getId());
                List<SkuAttrValueEntity> skuAttrValueEntities = skuAttrValueVO.getData();

                List<SearchAttrValueVo> searchAttrValueVos = new ArrayList<>();
                //把销售类型的检索属性和值放入当前集合
                if (!CollectionUtils.isEmpty(skuAttrValueEntities)) {
                    searchAttrValueVos.addAll(skuAttrValueEntities.stream().map(skuAttrValueEntity -> {
                        SearchAttrValueVo searchAttrValueVo = new SearchAttrValueVo();
                        BeanUtils.copyProperties(skuAttrValueEntity, searchAttrValueVo);
                        return searchAttrValueVo;
                    }).collect(Collectors.toList()));
                }

                ResponseVo<List<SpuAttrValueEntity>> spuAttrValueVO = pmsClient.querySpuAttrValuesByCidAndSpuId(spuEntity.getCategoryId(), spuEntity.getId());
                List<SpuAttrValueEntity> spuAttrValueEntities = spuAttrValueVO.getData();
                //把基本类型的检索属性和值放入当前集合
                if (!CollectionUtils.isEmpty(spuAttrValueEntities)) {
                    searchAttrValueVos.addAll(spuAttrValueEntities.stream().map(spuAttrValueEntity -> {
                        SearchAttrValueVo searchAttrValueVo = new SearchAttrValueVo();
                        BeanUtils.copyProperties(spuAttrValueEntity, searchAttrValueVo);
                        return searchAttrValueVo;
                    }).collect(Collectors.toList()));
                }

                //设置检索属性和值
                goods.setSearchAttrs(searchAttrValueVos);
                return goods;
            }).collect(Collectors.toList());

            //导入数据
            restTemplate.save(goodsList);
        } catch (IOException e) {
            e.printStackTrace();
            if (message.getMessageProperties().isRedelivered()){
                //拒绝接收消息
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
            }
            //不确认
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
        }
    }
}
